<?php

namespace App\Services\Order\AfterSale;

use App\Models\AfterSaleOrder;
use App\Models\Order;
use App\Services\Order\OperationBase;
use Carbon\Carbon;
use Symfony\Component\HttpKernel\Exception\HttpException;

abstract class PlaceAfterSaleOrder extends OperationBase
{
    protected $request;

    public function __construct($request)
    {
        $this->request = $request;
    }

    /**
     * @param null $order 下单时是 null
     */
    public function beforeHandle($order = null)
    {
        if ($order !== null) {
            if ($order->status !== Order::STATUS_SHIPPED) {
                abort(400, '您订单未处于已发货状态,当前不可进行售后操作');
            }
            if (Carbon::now()->startOfDay()->isAfter(Carbon::parse($order->commodityActivity['after_sale_deadline']))) {
                abort(400, '已经超出售后截止时间,当前不可进行售后操作');
            }
            if (((int) $this->request['type']) === AfterSaleOrder::TYPE_MAKE_UP) { // 当补偿时
                // 申请其他售后之后,不能再申请补偿
                // 是否有审核中和已通过的 售后
                if (AfterSaleOrder::query()
                    ->where('order_id', $order['id'])
                    ->whereIn('type', [AfterSaleOrder::TYPE_RETURN, AfterSaleOrder::TYPE_HEAVY_SHIPMENT, AfterSaleOrder::TYPE_REFUND_ONLY])
                    ->whereIn('status', [AfterSaleOrder::STATUS_PENDING_REVIEW, AfterSaleOrder::STATUS_FOLLOWING_UP, AfterSaleOrder::STATUS_PASSED])
                    ->exists()) {
                    abort(400, '已有其他审核中或已通过的售后申请,不能再提交补偿申请');
                }
            } else {
                // 申请补偿之后,不能再申请其他售后
                // 是否有审核中和已通过的补偿
                if (AfterSaleOrder::query()
                    ->where('order_id', $order['id'])
                    ->where('type', AfterSaleOrder::TYPE_MAKE_UP)
                    ->whereIn('status', [AfterSaleOrder::STATUS_PENDING_REVIEW, AfterSaleOrder::STATUS_FOLLOWING_UP, AfterSaleOrder::STATUS_PASSED])
                    ->exists()) {
                    abort(400, '已有其他审核中或已通过的补偿申请,不能再提交其他售后申请');
                }
            }
        }
    }

    public function afterHandle($order = null)
    {

    }

    /**
     * 提交的售后数量
     * @param Order $order
     */
    public function calculateSubmittedAfterSales(Order $order)
    {
        // 统计已经在售后的 sku_id => 数量
        $afterSaleOrderSku = [];
        $order->afterSaleOrder->each(function ($order) use (&$afterSaleOrderSku) {
            $order->afterSaleOrderSkus->each(function ($sku) use (&$afterSaleOrderSku) {
                $afterSaleOrderSku[$sku['commodity_activity_sku_id']] = ($afterSaleOrderSku[$sku['commodity_activity_sku_id']] ?? 0) + $sku['amount'];
            });
        });
        // 统计提交的售后 sku_id => 数量
        $submitSkuIdWithNum = [];
        foreach ($this->request['skus'] as $skuItem) {
            if (($skuItem['stepper_amount'] ?? 0) > 0) {
                $submitSkuIdWithNum[$skuItem['id']] = $skuItem['stepper_amount'] ?? 0;
            }
        }
        // 检查 order sku 是否够
        $totalAmountReturned = 0; // 本次退货涉及到的金额总数
        foreach ($order->skus as $sku) {
            // 订单的 SKU 数量 < 正在(或已)售后的数量 + 提交的数量
            if ($sku['amount'] < (($afterSaleOrderSku[$sku['id']] ?? 0) + ($submitSkuIdWithNum[$sku['id']] ?? 0))) {
                throw new HttpException(400, '提交的售后规格数量超出订单规格剩余可退数量');
            }

            $totalAmountReturned += $sku['unit_price'] * ($submitSkuIdWithNum[$sku['id']] ?? 0);
        }

        return [$totalAmountReturned, $submitSkuIdWithNum];
    }

    /**
     * 售后订单的 SKU 数据
     * @param $order
     * @param $afterSaleOrder
     * @param $submitSkuIdWithNum
     */
    public function createOrderSku($order, $afterSaleOrder, $submitSkuIdWithNum)
    {
        $createSku = [];
        $order->skus->each(function ($sku) use ($submitSkuIdWithNum, &$createSku) {
            if (isset($submitSkuIdWithNum[$sku['id']]) && $submitSkuIdWithNum[$sku['id']] > 0) {
                $createSku[] = array_merge(
                    ['amount' => $submitSkuIdWithNum[$sku['id']]],
                    $sku->only([
                        'order_id', 'commodity_id', 'commodity_activity_id', 'commodity_activity_sku_id',
                        'unit_price', 'sku_snapshot'
                    ]));
            }
        });
        $afterSaleOrder->afterSaleOrderSkus()->createMany($createSku);
    }
}
